//
// Created by 崔世强 on 2018/1/6.
// Copyright (c) 2018 Facebook. All rights reserved.
//

import Foundation
import UIKit

extension UIView {
    
    /**
     依照图片轮廓对控制进行裁剪
     
     - parameter stretchImage:  模子图片
     - parameter stretchInsets: 模子图片的拉伸区域
     */
    func clipShape(stretchImage: UIImage, stretchInsets: UIEdgeInsets) {
        // 绘制 imageView 的 bubble layer
        let bubbleMaskImage = stretchImage.resizableImage(withCapInsets: stretchInsets, resizingMode: .stretch)
        
        // 设置图片的mask layer
        let layer = CALayer()
        layer.contents = bubbleMaskImage.cgImage
        layer.contentsCenter = self.CGRectCenterRectForResizableImage(bubbleMaskImage)
        layer.frame = self.bounds
        layer.contentsScale = UIScreen.main.scale
        layer.opacity = 1
        self.layer.mask = layer
        self.layer.masksToBounds = true
    }
    
    func CGRectCenterRectForResizableImage(_ image: UIImage) -> CGRect {
        return CGRect(
            x: image.capInsets.left / image.size.width,
            y: image.capInsets.top / image.size.height,
            width: (image.size.width - image.capInsets.right - image.capInsets.left) / image.size.width,
            height: (image.size.height - image.capInsets.bottom - image.capInsets.top) / image.size.height
        )
    }
    
    /// 裁剪 view 的圆角
    func clipRectCorner(direction: UIRectCorner, cornerRadius: CGFloat) {
        let cornerSize = CGSize(width: cornerRadius, height: cornerRadius)
        let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: direction, cornerRadii: cornerSize)
        let maskLayer = CAShapeLayer()
        maskLayer.frame = bounds
        maskLayer.path = maskPath.cgPath
        layer.addSublayer(maskLayer)
        layer.mask = maskLayer
    }
    
    /// 将View画成图
    func trans2Image() -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(self.size, false, 0)
        let ctx = UIGraphicsGetCurrentContext()
        self.layer.render(in: ctx!)
        let newImg = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImg
    }
    
    public var x: CGFloat{
        get{
            return self.frame.origin.x
        }
        set{
            var r = self.frame
            r.origin.x = newValue
            self.frame = r
        }
    }
    
    public var y: CGFloat{
        get{
            return self.frame.origin.y
        }
        set{
            var r = self.frame
            r.origin.y = newValue
            self.frame = r
        }
    }
    /// 右边界的x值
    public var rightX: CGFloat{
        get{
            return self.x + self.width
        }
        set{
            var r = self.frame
            r.origin.x = newValue - frame.size.width
            self.frame = r
        }
    }
    /// 下边界的y值
    public var bottomY: CGFloat{
        get{
            return self.y + self.height
        }
        set{
            var r = self.frame
            r.origin.y = newValue - frame.size.height
            self.frame = r
        }
    }
    
    public var centerX : CGFloat{
        get{
            return self.center.x
        }
        set{
            self.center = CGPoint(x: newValue, y: self.center.y)
        }
    }
    
    public var centerY : CGFloat{
        get{
            return self.center.y
        }
        set{
            self.center = CGPoint(x: self.center.x, y: newValue)
        }
    }
    
    public var width: CGFloat{
        get{
            return self.frame.size.width
        }
        set{
            var r = self.frame
            r.size.width = newValue
            self.frame = r
        }
    }
    public var height: CGFloat{
        get{
            return self.frame.size.height
        }
        set{
            var r = self.frame
            r.size.height = newValue
            self.frame = r
        }
    }
    
    
    public var origin: CGPoint{
        get{
            return self.frame.origin
        }
        set{
            self.x = newValue.x
            self.y = newValue.y
        }
    }
    
    public var size: CGSize{
        get{
            return self.frame.size
        }
        set{
            self.width = newValue.width
            self.height = newValue.height
        }
    }
    
    /*----------------------------添加约束----------------------------*/
    
    /// 添加约束 -> edgeInsets
    func addLayoutConstraints(toItem: Any,edgeInsets: UIEdgeInsets) {
        addLayoutConstraints(attributes: [.top,.bottom,.left,.right], toItem: toItem, attributes: nil, constants:[edgeInsets.top,edgeInsets.bottom,edgeInsets.left,edgeInsets.right])
        
    }
    /// 添加约束 -> [attr1]丶toItem丶[attr2]丶constant
    func addLayoutConstraints(attributes attr1s: [NSLayoutConstraint.Attribute],
                              toItem: Any?,
                              attributes attr2s: [NSLayoutConstraint.Attribute]?,
                              constant: CGFloat) {
        for (i,attr1) in attr1s.enumerated() {
            let attr2 = attr2s == nil ? nil:attr2s![i]
            addLayoutConstraint(attribute: attr1, relatedBy: .equal, toItem: toItem, attribute: attr2, multiplier: 1, constant: constant)
        }
    }
    /// 添加约束 -> [attr1]丶toItem丶[attr2]丶[constant]
    func addLayoutConstraints(attributes attr1s: [NSLayoutConstraint.Attribute],
                              toItem: Any?,
                              attributes attr2s: [NSLayoutConstraint.Attribute]?,
                              constants: [CGFloat]) {
        for (i,attr1) in attr1s.enumerated() {
            let attr2 = attr2s == nil ? nil:attr2s![i]
            let constant = constants[i]
            addLayoutConstraint(attribute: attr1, toItem: toItem, attribute: attr2, constant: constant)
        }
    }
    /// 添加约束 -> attr1丶toItem丶attr2丶constant
    func addLayoutConstraint(attribute attr1: NSLayoutConstraint.Attribute,
                             toItem: Any?,
                             attribute attr2: NSLayoutConstraint.Attribute?,
                             constant: CGFloat) {
        addLayoutConstraint(attribute: attr1, relatedBy: .equal, toItem: toItem, attribute: attr2, multiplier: 1, constant: constant)
    }
    /// 添加约束 -> attr1丶relatedBy丶toItem丶attr2丶multiplier丶constant
    func addLayoutConstraint(attribute attr1: NSLayoutConstraint.Attribute,
                             relatedBy relation: NSLayoutConstraint.Relation,
                             toItem: Any?,
                             attribute attr2: NSLayoutConstraint.Attribute?,
                             multiplier: CGFloat,
                             constant: CGFloat) {
        
        var toItem = toItem
        var attr2 = attr2 ?? attr1
        
        if translatesAutoresizingMaskIntoConstraints == true {
            translatesAutoresizingMaskIntoConstraints = false
        }
        
        if attr1 == .width || attr1 == .height {
            toItem = nil
            attr2 = .notAnAttribute
        }
        
        let constraint = NSLayoutConstraint.init(item: self, attribute: attr1, relatedBy: relation, toItem: toItem, attribute: attr2, multiplier: multiplier, constant: constant)
        
        NSLayoutConstraint.activate([constraint])
    }
    
    /*----------------------------修改约束----------------------------*/
    
    /// 修改约束 -> edgeInsets
    func updateLayoutConstraints(toItem: Any,edgeInsets: UIEdgeInsets) {
        updateLayoutConstraints(attributes: [.top,.bottom,.left,.right], toItem: toItem, attributes: nil, constants:[edgeInsets.top,edgeInsets.bottom,edgeInsets.left,edgeInsets.right])
        
    }
    /// 修改约束 -> [attr1]丶toItem丶[attr2]丶constant
    func updateLayoutConstraints(attributes attr1s: [NSLayoutConstraint.Attribute],
                                 toItem: Any?,
                                 attributes attr2s: [NSLayoutConstraint.Attribute]?,
                                 constant: CGFloat) {
        for (i,attr1) in attr1s.enumerated() {
            let attr2 = attr2s == nil ? attr1:attr2s![i]
            updateLayoutConstraint(attribute: attr1, relatedBy: .equal, toItem: toItem, attribute: attr2, multiplier: 1, constant: constant)
        }
    }
    /// 修改约束 -> [attr1]丶toItem丶[attr2]丶[constant]
    func updateLayoutConstraints(attributes attr1s: [NSLayoutConstraint.Attribute],
                                 toItem: Any?,
                                 attributes attr2s: [NSLayoutConstraint.Attribute]?,
                                 constants: [CGFloat]) {
        for (i,attr1) in attr1s.enumerated() {
            let attr2 = attr2s == nil ? attr1:attr2s![i]
            let constant = constants[i]
            updateLayoutConstraint(attribute: attr1, toItem: toItem, attribute: attr2, constant: constant)
        }
    }
    /// 修改约束 -> attr1丶toItem丶attr2丶constant
    func updateLayoutConstraint(attribute attr1: NSLayoutConstraint.Attribute,
                                toItem: Any?,
                                attribute attr2: NSLayoutConstraint.Attribute?,
                                constant: CGFloat) {
        updateLayoutConstraint(attribute: attr1, relatedBy: .equal, toItem: toItem, attribute: attr2, multiplier: 1, constant: constant)
    }
    /// 修改约束 -> attr1丶relatedBy丶toItem丶attr2丶multiplier丶constant
    func updateLayoutConstraint(attribute attr1: NSLayoutConstraint.Attribute,
                                relatedBy relation: NSLayoutConstraint.Relation,
                                toItem: Any?,
                                attribute attr2: NSLayoutConstraint.Attribute?,
                                multiplier: CGFloat,
                                constant: CGFloat) {
        
        removeLayoutConstraint(attribute: attr1, toItem: toItem, attribute: attr2)
        
        addLayoutConstraint(attribute: attr1, relatedBy: relation, toItem: toItem, attribute: attr2, multiplier: multiplier, constant: constant)
    }
    
    /*----------------------------删除约束----------------------------*/
    
    /// 删除约束 -> [attr1]丶toItem丶[attr2]
    func removeLayoutConstraints(attributes attr1s: [NSLayoutConstraint.Attribute],
                                 toItem: Any?,
                                 attributes attr2s: [NSLayoutConstraint.Attribute]?) {
        for (i,attr1) in attr1s.enumerated() {
            let attr2 = attr2s == nil ? nil:attr2s![i]
            removeLayoutConstraint(attribute: attr1, toItem: toItem, attribute: attr2)
        }
    }
    /// 删除约束 -> attr1丶toItem丶attr2
    func removeLayoutConstraint(attribute attr1: NSLayoutConstraint.Attribute,
                                toItem: Any?,
                                attribute attr2: NSLayoutConstraint.Attribute?) {
        
        let attr2 = attr2 ?? attr1
        
        if attr1 == .width  || attr1 == .height {
            for constraint in constraints {
                if constraint.firstItem?.isEqual(self) == true &&
                    constraint.firstAttribute == attr1 {
                    NSLayoutConstraint.deactivate([constraint])
                }
            }
            
        }else if let superview = self.superview {
            for constraint in superview.constraints {
                if constraint.firstItem?.isEqual(self) == true &&
                    constraint.firstAttribute == attr1 &&
                    constraint.secondItem?.isEqual(toItem) == true &&
                    constraint.secondAttribute == attr2 {
                    NSLayoutConstraint.deactivate([constraint])
                }
            }
        }
    }
    
}
